/*
 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
 *
 * "The contents of this file are subject to the Mozilla Public License
 * Version 1.1 (the "License"); you may not use this file except in
 * compliance with the License. You may obtain a copy of the License at
 * http://www.mozilla.org/MPL/
 *
 * Software distributed under the License is distributed on an "AS IS"
 * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the
 * License for the specific language governing rights and limitations under
 * the License.
 *
 * The Original Code is ICEfaces 1.5 open source software code, released
 * November 5, 2006. The Initial Developer of the Original Code is ICEsoft
 * Technologies Canada, Corp. Portions created by ICEsoft are Copyright (C)
 * 2004-2006 ICEsoft Technologies Canada, Corp. All Rights Reserved.
 *
 * Contributor(s): _____________________.
 *
 * Alternatively, the contents of this file may be used under the terms of
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"
 * License), in which case the provisions of the LGPL License are
 * applicable instead of those above. If you wish to allow use of your
 * version of this file only under the terms of the LGPL License and not to
 * allow others to use your version of this file under the MPL, indicate
 * your decision by deleting the provisions above and replace them with
 * the notice and other provisions required by the LGPL License. If you do
 * not delete the provisions above, a recipient may use your version of
 * this file under either the MPL or the LGPL License."
 *
 */
package org.espe.sigec.web.utils;

import java.io.IOException;
import java.io.OutputStream;
import java.util.Collection;
import java.util.Map;

import javax.el.MethodExpression;
import javax.faces.FactoryFinder;
import javax.faces.application.Application;
import javax.faces.application.ApplicationFactory;
import javax.faces.application.FacesMessage;
import javax.faces.application.ViewHandler;
import javax.faces.component.UIViewRoot;
import javax.faces.context.ExternalContext;
import javax.faces.context.FacesContext;
import javax.faces.el.ValueBinding;
import javax.servlet.ServletContext;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpSession;

import org.espe.sigec.model.entities.Modulo;
import org.espe.sigec.model.entities.Opcion;
import org.richfaces.PanelMenuMode;
import org.richfaces.component.UICommandLink;
import org.richfaces.component.UIPanelMenu;
import org.richfaces.component.UIPanelMenuGroup;
import org.richfaces.component.UIPanelMenuItem;

/**
 * JSF utilities.
 */
@SuppressWarnings("deprecation")
public class FacesUtils {
    /**
     * Get servlet context.
     *
     * @return the servlet context
     */
    public static ServletContext getServletContext() {
        return (ServletContext) FacesContext.getCurrentInstance().getExternalContext().getContext();
    }

    public static ExternalContext getExternalContext() {
        FacesContext fc = FacesContext.getCurrentInstance();
        return fc.getExternalContext();
    }

    public static HttpSession getHttpSession(boolean create) {
        return (HttpSession) FacesContext.getCurrentInstance().
                getExternalContext().getSession(create);
    }

    /**
     * Get managed bean based on the bean name.
     *
     * @param beanName the bean name
     * @return the managed bean associated with the bean name
     */
    public static Object getManagedBean(String beanName) {

        return getValueBinding(getJsfEl(beanName)).getValue(FacesContext.getCurrentInstance());
    }

    /**
     * Remove the managed bean based on the bean name.
     *
     * @param beanName the bean name of the managed bean to be removed
     */
    public static void resetManagedBean(String beanName) {
        getValueBinding(getJsfEl(beanName)).setValue(FacesContext.getCurrentInstance(), null);
    }
    
    public static void removeManagedBean(String beanName) {
    	FacesContext.getCurrentInstance().getExternalContext().getSessionMap().remove(beanName);
    }
     
    /**
     * Store the managed bean inside the session scope.
     *
     * @param beanName    the name of the managed bean to be stored
     * @param managedBean the managed bean to be stored
     */
    public static void setManagedBeanInSession(String beanName, Object managedBean) {
        FacesContext.getCurrentInstance().getExternalContext().getSessionMap().put(beanName, managedBean);
    }

    /**
     * Get parameter value from request scope.
     *
     * @param name the name of the parameter
     * @return the parameter value
     */
    public static String getRequestParameter(String name) {
        return (String) FacesContext.getCurrentInstance().getExternalContext().getRequestParameterMap().get(name);
    }

    /**
     * Add information message.
     *
     * @param msg the information message
     */
    public static void addInfoMessage(String msg) {
        addInfoMessage(null, msg);
    }

    /**
     * Add information message to a specific client.
     *
     * @param clientId the client id
     * @param msg      the information message
     */
    public static void addInfoMessage(String clientId, String msg) {
        FacesContext.getCurrentInstance().addMessage(clientId, new FacesMessage(FacesMessage.SEVERITY_INFO, msg, msg));
    }

    /**
     * Add error message.
     *
     * @param msg the error message
     */
    public static void addErrorMessage(String msg) {
        addErrorMessage(null, msg);
    }

    /**
     * Add error message to a specific client.
     *
     * @param clientId the client id
     * @param msg      the error message
     */
    public static void addErrorMessage(String clientId, String msg) {
        FacesContext.getCurrentInstance().addMessage(clientId, new FacesMessage(FacesMessage.SEVERITY_ERROR, msg, msg));
    }

    private static Application getApplication() {
        ApplicationFactory appFactory = (ApplicationFactory) FactoryFinder.getFactory(FactoryFinder.APPLICATION_FACTORY);
        return appFactory.getApplication();
    }

    private static ValueBinding getValueBinding(String el) {
        return getApplication().createValueBinding(el);
    }

    @SuppressWarnings("unused")
	private static HttpServletRequest getServletRequest() {
        return (HttpServletRequest) FacesContext.getCurrentInstance().getExternalContext().getRequest();
    }

    @SuppressWarnings("unused")
	private static Object getElValue(String el) {
        return getValueBinding(el).getValue(FacesContext.getCurrentInstance());
    }

    private static String getJsfEl(String value) {
        return "#{" + value + "}";
    }
    
    public static void putFlashObject (String key, Object object){
    	FacesContext.getCurrentInstance().getExternalContext().getFlash().put(key, object);
    }
    
    public static Object getFlashObject (String key){
    	return FacesContext.getCurrentInstance().getExternalContext().getFlash().get(key);
    }
    public static Object removeFlashObject (String key){
    	return FacesContext.getCurrentInstance().getExternalContext().getFlash().remove(key);
    }
    
    public static void putSessionObject (String key, Object object){
    	ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
    	Map<String, Object> sessionMap = externalContext.getSessionMap();
    	sessionMap.put(key, object);
    }
    
    public static Object getSessionObject (String key){
    	ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
    	Map<String, Object> sessionMap = externalContext.getSessionMap();
    	return sessionMap.get(key);
    }
    
    
    public static void refresh() {  
	    FacesContext context = FacesContext.getCurrentInstance();  
	    Application application = context.getApplication();  
	    ViewHandler viewHandler = application.getViewHandler();  
	    UIViewRoot viewRoot = viewHandler.createView(context, context.getViewRoot().getViewId());  
	    context.setViewRoot(viewRoot);  
	    context.renderResponse(); //Optional  
	}
    
    public static UIPanelMenu buildUserMenu(final Collection<Modulo> lstModulos){
    	UIPanelMenu uiPanelMenu = new UIPanelMenu();
		uiPanelMenu.setItemMode(PanelMenuMode.client);
		uiPanelMenu.setGroupMode(PanelMenuMode.client);
		uiPanelMenu.setGroupCollapsedLeftIcon("triangleDown");
		uiPanelMenu.setGroupExpandedLeftIcon("triangleUp");
		uiPanelMenu.setTopGroupExpandedRightIcon("chevronUp");
		uiPanelMenu.setTopGroupCollapsedRightIcon("chevronDown");
		uiPanelMenu.setItemLeftIcon("disc");
		
		UIPanelMenuGroup uiPanelMenuGroup = null;
		for(Modulo modulo: lstModulos){
			uiPanelMenuGroup = new UIPanelMenuGroup();
			uiPanelMenuGroup.setLabel(modulo.getNombre());
			
			if(modulo.getOpcionCollection() != null && !modulo.getOpcionCollection().isEmpty()){
				UIPanelMenuItem panelMenuItem = null;
//				UICommandLink uiCommandLink = null;
				UICommandLink uiCommandLink ;
				for(Opcion opcion: modulo.getOpcionCollection()){
					panelMenuItem = new UIPanelMenuItem();
//					uiCommandLink = new UICommandLink();
					uiCommandLink = new UICommandLink();
					panelMenuItem.setName(opcion.getNombre());
					uiCommandLink.setValue(opcion.getNombre());
					uiCommandLink.setTarget(opcion.getTargetUrl());
					
					uiCommandLink.setExecute("@this");
//					uiCommandLink.setRender("@all");
					@SuppressWarnings("rawtypes")
					Class[] params = {};
//					MethodExpression actionExpression = FacesContext.getCurrentInstance().getApplication().getExpressionFactory()
//				               .createMethodExpression(FacesContext.getCurrentInstance().getELContext(),
//				            		   "#{homeSessionController.menuAction('"+opcion.getDescripcion()+"')}", String.class, params);
					MethodExpression actionExpression = FacesContext.getCurrentInstance().getApplication().getExpressionFactory()
				               .createMethodExpression(FacesContext.getCurrentInstance().getELContext(),
				            		   opcion.getTargetUrl()+"?faces-redirect=true", String.class, params);
					
					uiCommandLink.setActionExpression(actionExpression);
					uiCommandLink.setHreflang(opcion.getTargetUrl());
					panelMenuItem.getChildren().add(uiCommandLink);
					uiPanelMenuGroup.getChildren().add(panelMenuItem);
				}
			}
			if(modulo.getOpcionCollection() != null && !modulo.getOpcionCollection().isEmpty()){
				uiPanelMenu.getChildren().add(uiPanelMenuGroup);
			}
		}
		return uiPanelMenu;
	}
    public static void redirectPage(String page) throws IOException{
    	getExternalContext().redirect(page);
    }
    
    public static OutputStream getTempletaDescargaReporte(String nombreArchivoDoc) throws IOException{
    	FacesContext facesContext = FacesContext.getCurrentInstance();
	    ExternalContext externalContext = facesContext.getExternalContext();
	    externalContext.setResponseContentType("application/vnd.ms-word");
	    externalContext.setResponseHeader("Content-Disposition", "attachment; filename=\""+nombreArchivoDoc+"\"");
	    return externalContext.getResponseOutputStream();
    }
}
